<template>
  <el-dialog
    v-model="dialogVisible"
    title="打卡活动记录详情"
    width="1200px"
    :close-on-click-modal="false"
  >
    <div v-loading="loading" class="detail-content">
      <template v-if="recordData">
        <!-- 活动删除警告 -->
        <el-alert
          v-if="!recordData.activityName"
          title="活动已删除"
          type="warning"
          description="该活动已被删除，无法进行审核和退款操作"
          :closable="false"
          show-icon
          class="mb-4"
        />

        <!-- 用户信息 -->
        <div class="info-section">
          <div class="info-row">
            <span class="info-label">用户名称：</span>
            <span class="info-value">{{ recordData.userName }}</span>
            <span class="info-label ml-8">手机号码：</span>
            <span class="info-value">{{ recordData.mobile }}</span>
          </div>
          <div class="info-row">
            <span class="info-label">活动名称：</span>
            <span class="info-value">{{ recordData.activityName }}</span>
            <span class="info-label ml-8">商品：</span>
            <span class="info-value">{{ recordData.productName }}</span>
          </div>
          <div class="info-row">
            <span class="info-label">当前阶段：</span>
            <el-tag
              :type="getStageTagType(recordData.stage, recordData.activityUploadProof, recordData.activityName, recordData.hasClosed)"
              size="large"
            >
              {{ getStageText(recordData.stage, recordData.activityUploadProof, recordData.activityName, recordData.hasClosed) }}
            </el-tag>
            <span class="info-label ml-8">打卡规则：</span>
            <span class="info-value">{{ getPunchRuleText(recordData.punchCardRule) }}</span>
          </div>
          <!-- 终止原因显示 -->
          <div v-if="recordData.hasClosed && recordData.closeReason" class="info-row">
            <span class="info-label">终止原因：</span>
            <span class="info-value close-reason">{{ recordData.closeReason }}</span>
          </div>
        </div>

        <!-- 活动前后照片 -->
        <div v-if="recordData.beforeImage || recordData.afterImage" class="photos-section">
          <div v-if="recordData.beforeImage" class="photo-item">
            <div class="photo-label">活动前照片：</div>
            <div class="photo-container">
              <img
                :src="recordData.beforeImage"
                alt="活动前照片"
                class="activity-photo"
                @click="previewImage(recordData.beforeImage)"
              />
            </div>
          </div>
          <div v-if="recordData.afterImage" class="photo-item">
            <div class="photo-label">活动后照片：</div>
            <div class="photo-container">
              <img
                :src="recordData.afterImage"
                alt="活动后照片"
                class="activity-photo"
                @click="previewImage(recordData.afterImage)"
              />
            </div>
          </div>
        </div>

        <!-- 审核流程 -->
        <div class="review-section">
          <div class="section-title">审核流程</div>
          <div class="review-timeline">
            <!-- 显示预期的审核步骤和实际数据 -->
            <div
              v-for="(step, index) in getExpectedSteps"
              :key="step.id"
              class="timeline-item"
            >
              <div class="timeline-dot" :class="getStepDotClass(step, index)">
                <Icon
                  :icon="getStepIcon(step, index)"
                  class="timeline-icon"
                  :class="getStepIconClass(step, index)"
                />
              </div>

              <div class="timeline-main">
                <div class="timeline-header">
                  <div class="timeline-title">
                    {{ step.title }}
                  </div>
                  <div class="timeline-meta">
                    <span v-if="step.actualData?.uploadTime && step.id !== 2" class="timeline-time">{{ step.actualData.uploadTime }}</span>
                  </div>
                </div>

                <div class="timeline-content">
                  <!-- 如果没有实际数据，显示等待状态 -->
                  <div v-if="!step.actualData || !step.actualData.images || step.actualData.images.length === 0" class="no-upload">
                    <Icon icon="ep:clock" class="pending-icon" />
                    <span>{{ getStepWaitingText(step, index) }}</span>
                  </div>
                  <!-- 如果有实际数据，显示审核资料 -->
                  <div v-else class="review-images">
                    <!-- 如果是打卡记录审核且有按天分组的数据，按天展示 -->
                    <div v-if="step.id === 2 && step.actualData.dailyRecords && step.actualData.dailyRecords.length > 0" class="daily-records">
                      <div
                        v-for="dailyRecord in step.actualData.dailyRecords"
                        :key="dailyRecord.date"
                        class="daily-record-group"
                      >
                        <div class="daily-record-header">
                          <div class="daily-date">
                            <Icon icon="ep:calendar" class="calendar-icon" />
                            {{ formatDate(dailyRecord.date) }}
                          </div>
                          <div class="daily-status">
                            <el-tag
                              :type="dailyRecord.allApproved ? 'success' : 'warning'"
                              size="small"
                            >
                              {{ dailyRecord.allApproved ? '全部通过' : '待审核' }}
                            </el-tag>
                          </div>
                        </div>
                        <div class="daily-images">
                          <div
                            v-for="image in dailyRecord.images"
                            :key="image.id"
                            class="image-item"
                            @click="handleImageReview(image)"
                          >
                            <div class="image-wrapper">
                              <img
                                v-if="image.type === 'image'"
                                :src="image.url"
                                alt="审核资料"
                                class="review-image"
                              />
                              <video
                                v-else
                                :src="image.url"
                                class="review-image"
                                muted
                                preload="metadata"
                                @click.stop
                              >
                                您的浏览器不支持视频播放
                              </video>
                              <div class="image-overlay">
                                <Icon
                                  :icon="image.type === 'image' ? 'ep:picture' : 'ep:video-play'"
                                  class="media-icon"
                                />
                                <div v-if="image.type === 'video'" class="video-tip">点击审核</div>
                              </div>
                            </div>
                            <div class="image-status">
                              <el-tag
                                :type="getStatusTagType(image.status)"
                                size="small"
                              >
                                {{ getStatusText(image.status) }}
                              </el-tag>
                              <div v-if="image.comment && image.status === 'rejected'" class="review-comment">
                                <Icon icon="ep:chat-dot-square" />
                                {{ image.comment }}
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                    <!-- 其他类型审核的原有展示方式 -->
                    <div v-else class="normal-images">
                      <div
                        v-for="image in step.actualData.images"
                        :key="image.id"
                        class="image-item"
                        @click="handleImageReview(image)"
                      >
                        <div class="image-wrapper">
                          <img
                            v-if="image.type === 'image'"
                            :src="image.url"
                            alt="审核资料"
                            class="review-image"
                          />
                          <video
                            v-else
                            :src="image.url"
                            class="review-image"
                            muted
                            preload="metadata"
                            @click.stop
                          >
                            您的浏览器不支持视频播放
                          </video>
                          <div class="image-overlay">
                            <Icon
                              :icon="image.type === 'image' ? 'ep:picture' : 'ep:video-play'"
                              class="media-icon"
                            />
                            <div v-if="image.type === 'video'" class="video-tip">点击审核</div>
                          </div>
                        </div>
                        <div class="image-status">
                          <el-tag
                            :type="getStatusTagType(image.status)"
                            size="small"
                          >
                            {{ getStatusText(image.status) }}
                          </el-tag>
                          <div v-if="image.comment && image.status === 'rejected'" class="review-comment">
                            <Icon icon="ep:chat-dot-square" />
                            {{ image.comment }}
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 操作按钮区域 -->
        <div v-if="canRefund || canClose" class="action-section">
          <!-- 终止按钮 -->
          <el-button
            v-if="canClose"
            type="warning"
            size="large"
            @click="handleClose"
            :loading="closing"
          >
            终止打卡
          </el-button>
          <!-- 退款按钮 -->
          <el-button
            v-if="canRefund"
            type="danger"
            size="large"
            @click="handleRefund"
            :loading="refunding"
          >
            {{ getRefundButtonText }}
          </el-button>
        </div>
      </template>
    </div>

    <template #footer>
      <el-button @click="dialogVisible = false">关闭</el-button>
    </template>
  </el-dialog>

  <!-- 审核 Modal -->
  <ReviewModal
    ref="reviewModalRef"
    @refresh="refreshData"
  />

  <!-- 终止活动 Modal -->
  <el-dialog
    v-model="closeDialogVisible"
    title="终止打卡"
    width="500px"
    :close-on-click-modal="false"
  >
    <el-form
      ref="closeFormRef"
      :model="closeForm"
      :rules="closeRules"
      label-width="80px"
    >
      <el-form-item label="终止原因" prop="closeReason">
        <el-input
          v-model="closeForm.closeReason"
          type="textarea"
          :rows="4"
          placeholder="请输入终止原因"
          maxlength="200"
          show-word-limit
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="closeDialogVisible = false">取消</el-button>
      <el-button
        type="primary"
        @click="confirmClose"
        :loading="closing"
      >
        确认终止
      </el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import * as RefundActivityRecordApi from '@/api/mall/promotion/refund/activityRecord'
import type { RefundActivityRecordVO, CheckInImageVO, DailyCheckInRecordVO, RefundActivityRecordCloseReqVO } from '@/api/mall/promotion/refund/activityRecord'
import ReviewModal from './ReviewModal.vue'

/** 格式化日期显示 */
const formatDate = (dateStr: string) => {
  const date = new Date(dateStr)
  const today = new Date()
  const yesterday = new Date(today)
  yesterday.setDate(yesterday.getDate() - 1)

  const isToday = date.toDateString() === today.toDateString()
  const isYesterday = date.toDateString() === yesterday.toDateString()

  if (isToday) {
    return `今天 ${dateStr}`
  } else if (isYesterday) {
    return `昨天 ${dateStr}`
  } else {
    return dateStr
  }
}

defineOptions({ name: 'DetailModal' })

const emit = defineEmits(['refresh'])
const message = useMessage()
const router = useRouter()

const dialogVisible = ref(false)
const loading = ref(false)
const refunding = ref(false)
const recordData = ref<RefundActivityRecordVO>()

// 终止活动相关
const closeDialogVisible = ref(false)
const closing = ref(false)
const closeFormRef = ref()
const closeForm = reactive({
  closeReason: ''
})
const closeRules = {
  closeReason: [
    { required: true, message: '请输入终止原因', trigger: 'blur' },
    { min: 5, max: 200, message: '终止原因长度在 5 到 200 个字符', trigger: 'blur' }
  ]
}

/** 打开弹窗 */
const open = async (id: number) => {
  dialogVisible.value = true
  loading.value = true
  try {
    const data = await RefundActivityRecordApi.getRefundActivityRecord(id)
    recordData.value = data as RefundActivityRecordVO
  } finally {
    loading.value = false
  }
}

/** 刷新数据 */
const refreshData = async () => {
  if (recordData.value?.id) {
    loading.value = true
    try {
      const data = await RefundActivityRecordApi.getRefundActivityRecord(recordData.value.id)
      recordData.value = data as RefundActivityRecordVO
    } finally {
      loading.value = false
    }
  }
}

/** 检查是否显示退款按钮 */
const canRefund = computed(() => {
  if (!recordData.value) return false

  // 如果活动已被删除，不显示退款按钮
  if (!recordData.value.activityName) return false

  // 只有当isAfterSale为true时才显示退款按钮
  return !!recordData.value.isAfterSale
})

/** 检查是否显示终止按钮 */
const canClose = computed(() => {
  if (!recordData.value) return false

  // 如果活动已被删除，不显示终止按钮
  if (!recordData.value.activityName) return false

  // 如果已经终止，不显示终止按钮
  if (recordData.value.hasClosed) return false

  // 检查当前阶段是否已完成
  const stageText = getStageText(
    recordData.value.stage,
    recordData.value.activityUploadProof,
    recordData.value.activityName,
    recordData.value.hasClosed
  )

  // 如果当前阶段是"已完成"，不显示终止按钮
  if (stageText === '已完成') return false

  // 只有进行中的活动才能终止
  return true
})

/** 获取退款按钮文案 */
const getRefundButtonText = computed(() => {
  return '退款'
})

/** 处理退款按钮点击 */
const handleRefund = async () => {
  if (!recordData.value || !recordData.value.afterSaleId) {
    message.error('售后ID不存在，无法跳转')
    return
  }

  // 跳转到售后详情页面
  await router.push(`/mall/trade/after-sale/detail/${recordData.value.afterSaleId}`)
  // 关闭当前Modal
  dialogVisible.value = false
}

/** 处理终止按钮点击 */
const handleClose = () => {
  closeForm.closeReason = ''
  closeDialogVisible.value = true
}

/** 确认终止活动 */
const confirmClose = async () => {
  if (!recordData.value) return

  // 表单验证
  const valid = await closeFormRef.value?.validate()
  if (!valid) return

  try {
    closing.value = true

    const closeData: RefundActivityRecordCloseReqVO = {
      id: recordData.value.id,
      hasClosed: true,
      closeReason: closeForm.closeReason
    }

    await RefundActivityRecordApi.closeRefundActivityRecord(closeData)

    message.success('活动终止成功')
    closeDialogVisible.value = false

    // 刷新数据
    await refreshData()

    // 通知父组件刷新列表
    emit('refresh')
  } catch (error) {
    console.error('终止活动失败:', error)
    message.error('终止活动失败，请重试')
  } finally {
    closing.value = false
  }
}

/** 预览图片 */
const previewImage = (url?: string) => {
  if (url) {
    // 使用 Element Plus 的图片预览
    window.open(url, '_blank')
  }
}

/** 处理图片审核 */
const reviewModalRef = ref()
const handleImageReview = (image: CheckInImageVO) => {
  if (!recordData.value?.activityName) {
    message.warning('该活动已被删除，无法进行审核操作')
    return
  }

  // 判断当前步骤是否可以审核
  const canReview = isStepReviewable(image)
  reviewModalRef.value.open(image, canReview)
}

/** 判断某个步骤是否可以审核 */
const isStepReviewable = (image: CheckInImageVO) => {
  if (!recordData.value) return false

  const currentStage = recordData.value.stage
  const expectedSteps = getExpectedSteps.value

  // 找到这个image所属的step
  const parentStep = expectedSteps.find(step =>
    step.actualData?.images?.some((img: any) => img.id === image.id)
  )

  if (!parentStep) return false

  // 获取当前步骤对应的实际step id
  const currentStepId = getCurrentStepId(currentStage, expectedSteps)

  // 获取最后一个步骤的ID
  const lastStepId = expectedSteps.length > 0 ? expectedSteps[expectedSteps.length - 1].id : 0

  // 如果stage超过最后一个步骤，说明已完成所有步骤
  if (currentStepId > lastStepId) {
    return false
  }

  // 只有当前步骤可以审核
  if (parentStep.id === currentStepId) {
    // 检查是否有待审核的图片
    const hasPendingImages = parentStep.actualData?.images?.some((img: any) => img.status === 'pending')
    return hasPendingImages || false
  }

  return false
}

/** 获取状态标签类型 */
const getStatusTagType = (status: string) => {
  switch (status) {
    case 'approved':
      return 'success'
    case 'rejected':
      return 'danger'
    default:
      return 'warning'
  }
}

/** 获取状态文本 */
const getStatusText = (status: string) => {
  switch (status) {
    case 'approved':
      return '审核通过'
    case 'rejected':
      return '审核未通过'
    default:
      return '待审核'
  }
}

/** 获取阶段标签类型 */
const getStageTagType = (stage: number, activityUploadProof?: boolean, activityName?: string, hasClosed?: boolean) => {
  // 优先检查活动是否被删除
  if (!activityName) {
    return 'danger'
  }

  // 检查打卡是否已终止
  if (hasClosed === true) {
    return 'danger'
  }

  // 处理activityUploadProof为undefined或null的情况
  const needUploadProof = activityUploadProof === true

  // 如果不需要上传凭证，只有2个阶段
  if (!needUploadProof) {
    switch (stage) {
      case 1:
        return 'warning'
      case 2:
        return 'success' // 第2阶段就是完成状态
      default:
        // 对于未知阶段，根据数值范围给出合理的标签类型
        if (stage <= 0) {
          return 'info'
        } else if (stage > 2) {
          return 'success'
        } else {
          return 'danger'
        }
    }
  }

  // 需要上传凭证时，有更多阶段
  switch (stage) {
    case 1:
      return 'warning'
    case 2:
      return 'warning'
    case 3:
      return 'success'
    case 4:
      return 'success'
    default:
      // 对于未知阶段，根据数值范围给出合理的标签类型
      if (stage <= 0) {
        return 'info'
      } else if (stage > 4) {
        return 'success'
      } else {
        return 'danger'
      }
  }
}

/** 获取阶段文本 */
const getStageText = (stage: number, activityUploadProof?: boolean, activityName?: string, hasClosed?: boolean) => {
  // 优先检查活动是否被删除
  if (!activityName) {
    return '活动已删除'
  }

  // 检查打卡是否已终止
  if (hasClosed === true) {
    return '打卡已终止'
  }

  // 处理activityUploadProof为undefined或null的情况
  const needUploadProof = activityUploadProof === true

  // 如果不需要上传凭证，只有2个阶段
  if (!needUploadProof) {
    switch (stage) {
      case 1:
        return '进行中'
      case 2:
        return '已完成' // 第2阶段就是完成状态
      default:
        // 对于未知阶段，根据数值范围给出合理的文本
        if (stage <= 0) {
          return '未开始'
        } else if (stage > 2) {
          return '已完成'
        } else {
          return '未知阶段'
        }
    }
  }

  // 需要上传凭证时，有更多阶段
  switch (stage) {
    case 1:
      return '进行中'
    case 2:
      return '进行中'
    case 3:
      return '已完成'
    case 4:
      return '已完成'
    default:
      // 对于未知阶段，根据数值范围给出合理的文本
      if (stage <= 0) {
        return '未开始'
      } else if (stage > 4) {
        return '已完成'
      } else {
        return '未知阶段'
      }
  }
}

/** 获取阶段图标 */
const getStageIcon = (id: number) => {
  switch (id) {
    case 1:
      return 'ep:clock'
    case 2:
      return 'ep:loading'
    case 3:
      return 'ep:check'
    case 4:
      return 'ep:check'
    default:
      return 'ep:question'
  }
}

/** 获取阶段图标类名 */
const getStageIconClass = (record: any) => {
  return {
    'stage-icon': true,
    'stage-icon-pending': record.id === 1,
    'stage-icon-processing': record.id === 2,
    'stage-icon-completed': record.id === 3 || record.id === 4
  }
}

/** 获取打卡规则文本 */
const getPunchRuleText = (rule: number) => {
  switch (rule) {
    case 1:
      return '持续打卡'
    case 2:
      return '非持续打卡'
    case 3:
      return '无需打卡'
    default:
      return '未设置打卡规则'
  }
}



/** 根据业务规则获取预期的审核步骤 */
const getExpectedSteps = computed(() => {
  if (!recordData.value) return []

  const steps = []
  const { punchCardRule, activityUploadProof, checkInRecords } = recordData.value

  // 将后端数据按type分组，方便查找
  const recordsMap = (checkInRecords || []).reduce((acc, record) => {
    acc[record.id] = record
    return acc
  }, {} as Record<number, any>)

  // 业务逻辑重新梳理：
  // activityUploadProof = false: 只有打卡记录审核
  // activityUploadProof = true: 有活动健康报告审核 + 可能有打卡记录审核 + 活动期后上传凭证审核

  // 处理activityUploadProof为undefined或null的情况
  const needUploadProof = activityUploadProof === true

  if (!needUploadProof) {
    // 如果不需要活动期后上传凭证，只有打卡记录审核
    if (punchCardRule !== 3) {
      steps.push({
        id: 2,
        title: '打卡记录审核',
        actualData: recordsMap[2] || null
      })
    }
  } else {
    // 如果需要活动期后上传凭证，有完整流程

    // 第一步：活动健康报告审核（type=1）
    steps.push({
      id: 1,
      title: '活动健康报告审核',
      actualData: recordsMap[1] || null
    })

    // 根据 punchCardRule 决定是否有打卡步骤（type=2）
    if (punchCardRule !== 3) {
      // punchCardRule 不为 3，需要打卡
      steps.push({
        id: 2,
        title: '打卡记录审核',
        actualData: recordsMap[2] || null
      })
    }

    // 活动期后上传凭证审核（type=3）
    steps.push({
      id: 3,
      title: '活动期后上传凭证审核',
      actualData: recordsMap[3] || null
    })
  }

  return steps
})

/** 根据stage和预期步骤获取当前步骤ID */
const getCurrentStepId = (currentStage: number, expectedSteps: any[]) => {
  if (expectedSteps.length === 0) return 1

  // 根据stage在预期步骤中的位置找到对应的step id
  const stepIndex = currentStage - 1 // stage从1开始，转为从0开始的索引

  if (stepIndex < expectedSteps.length) {
    return expectedSteps[stepIndex].id
  } else {
    // 如果stage超过了步骤数量，返回最后一个步骤的id + 1（表示已完成所有步骤）
    return expectedSteps[expectedSteps.length - 1].id + 1
  }
}

/** 获取步骤等待文本 */
const getStepWaitingText = (step: any, index: number) => {
  if (!recordData.value) return '等待用户上传资料'

  const currentStage = recordData.value.stage
  const expectedSteps = getExpectedSteps.value
  const currentStepId = getCurrentStepId(currentStage, expectedSteps)

  if (step.id > currentStepId) {
    // 还没到这个步骤
    return '等待前置步骤完成'
  } else if (step.id === currentStepId) {
    // 当前步骤
    return '等待用户上传资料'
  } else {
    // 已过步骤但无数据
    return '用户未上传资料'
  }
}

/** 获取步骤图标 */
const getStepIcon = (step: any, index: number) => {
  if (!recordData.value) return 'ep:clock'

  const currentStage = recordData.value.stage
  const expectedSteps = getExpectedSteps.value
  const hasData = step.actualData && step.actualData.images && step.actualData.images.length > 0

  // 获取当前步骤对应的实际step id
  const currentStepId = getCurrentStepId(currentStage, expectedSteps)

  if (step.id < currentStepId) {
    // 已完成的步骤
    if (hasData) {
      const allApproved = step.actualData.images.every((img: any) => img.status === 'approved')
      return allApproved ? 'ep:check' : 'ep:close'
    } else {
      return 'ep:minus' // 跳过的步骤
    }
  } else if (step.id === currentStepId) {
    // 当前步骤
    return hasData ? 'ep:loading' : 'ep:clock'
  } else {
    // 未来步骤
    return 'ep:clock'
  }
}

/** 获取步骤图标类名 */
const getStepIconClass = (step: any, index: number) => {
  if (!recordData.value) return { 'timeline-icon-pending': true }

  const currentStage = recordData.value.stage
  const expectedSteps = getExpectedSteps.value
  const hasData = step.actualData && step.actualData.images && step.actualData.images.length > 0

  // 获取当前步骤对应的实际step id
  const currentStepId = getCurrentStepId(currentStage, expectedSteps)

  if (step.id < currentStepId) {
    // 已完成的步骤
    if (hasData) {
      const allApproved = step.actualData.images.every((img: any) => img.status === 'approved')
      return {
        'timeline-icon-completed': allApproved,
        'timeline-icon-rejected': !allApproved
      }
    } else {
      return { 'timeline-icon-skipped': true }
    }
  } else if (step.id === currentStepId) {
    // 当前步骤
    return { 'timeline-icon-processing': true }
  } else {
    // 未来步骤
    return { 'timeline-icon-pending': true }
  }
}

/** 获取步骤圆点类名 */
const getStepDotClass = (step: any, index: number) => {
  if (!recordData.value) return { 'timeline-dot-pending': true }

  const currentStage = recordData.value.stage
  const expectedSteps = getExpectedSteps.value
  const hasData = step.actualData && step.actualData.images && step.actualData.images.length > 0

  // 获取当前步骤对应的实际step id
  const currentStepId = getCurrentStepId(currentStage, expectedSteps)

  if (step.id < currentStepId) {
    // 已完成的步骤
    if (hasData) {
      const allApproved = step.actualData.images.every((img: any) => img.status === 'approved')
      return {
        'timeline-dot-completed': allApproved,
        'timeline-dot-rejected': !allApproved
      }
    } else {
      return { 'timeline-dot-skipped': true }
    }
  } else if (step.id === currentStepId) {
    // 当前步骤
    return { 'timeline-dot-processing': true }
  } else {
    // 未来步骤
    return { 'timeline-dot-pending': true }
  }
}

defineExpose({
  open
})
</script>

<style scoped>
.detail-content {
  padding: 20px 0;
}

.info-section {
  margin-bottom: 30px;
}

.info-row {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.info-label {
  font-weight: 500;
  color: #606266;
  min-width: 80px;
}

.info-value {
  color: #303133;
  margin-right: 20px;
}

.photos-section {
  display: flex;
  gap: 40px;
  margin-bottom: 30px;
}

.photo-item {
  flex: 1;
}

.photo-label {
  font-weight: 500;
  margin-bottom: 10px;
  color: #303133;
}

.photo-container {
  width: 100%;
  height: 200px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
}

.activity-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.review-section {
  margin-bottom: 30px;
}

.section-title {
  font-weight: 500;
  color: #303133;
  margin-bottom: 10px;
}

.review-timeline {
  background: #f5f7fa;
  padding: 20px;
  border-radius: 8px;
}

.timeline-item {
  display: flex;
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid #e4e7ed;
  position: relative;
}

.timeline-item:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.timeline-item:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 9px;
  top: 30px;
  bottom: -20px;
  width: 2px;
  background: #e4e7ed;
}

.timeline-dot {
  position: relative;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #e4e7ed;
  margin-right: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

.timeline-icon {
  font-size: 12px;
}

.timeline-icon-pending {
  color: #e6a23c;
}

.timeline-icon-processing {
  color: #409eff;
}

.timeline-icon-completed {
  color: #67c23a;
}

.timeline-icon-rejected {
  color: #f56c6c;
}

.timeline-icon-skipped {
  color: #909399;
}

.timeline-dot-pending {
  border-color: #e6a23c;
}

.timeline-dot-processing {
  border-color: #409eff;
}

.timeline-dot-completed {
  border-color: #67c23a;
}

.timeline-dot-rejected {
  border-color: #f56c6c;
}

.timeline-dot-skipped {
  border-color: #909399;
}

.timeline-main {
  flex: 1;
}

.timeline-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.timeline-title {
  font-weight: 500;
  color: #303133;
  font-size: 14px;
}

.timeline-meta {
  display: flex;
  gap: 12px;
  font-size: 12px;
  color: #909399;
}

.timeline-date {
  font-weight: 500;
}

.timeline-time {
  opacity: 0.8;
}

.timeline-content {
  flex: 1;
}

.no-upload {
  color: #909399;
  font-style: italic;
}

/* 按天分组的打卡记录样式 */
.daily-records {
  margin-top: 10px;
}

.daily-record-group {
  margin-bottom: 20px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  overflow: hidden;
}

.daily-record-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #e4e7ed;
}

.daily-date {
  display: flex;
  align-items: center;
  font-weight: 500;
  color: #303133;
  font-size: 14px;
}

.calendar-icon {
  margin-right: 8px;
  color: #409eff;
}

.daily-images {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  padding: 16px;
}

/* 普通展示方式和按天分组共用的样式 */
.review-images {
  /* 容器样式 */
}

.normal-images {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.image-item {
  cursor: pointer;
  transition: transform 0.2s;
}

.image-item:hover {
  transform: scale(1.05);
}

.image-wrapper {
  position: relative;
  width: 120px;
  height: 90px;
  border-radius: 6px;
  overflow: hidden;
  border: 2px solid #e4e7ed;
}

.review-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.review-image[controls] {
  /* 视频控件样式调整 */
  outline: none;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.2s;
}

.image-item:hover .image-overlay {
  opacity: 1;
}

.media-icon {
  color: white;
  font-size: 24px;
}

.video-tip {
  color: white;
  font-size: 12px;
  margin-top: 5px;
  text-align: center;
}

.image-status {
  margin-top: 5px;
  text-align: center;
}

.review-comment {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.no-upload {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pending-icon {
  color: #909399;
}

.stage-icon-pending {
  color: #e6a23c;
}

.stage-icon-processing {
  color: #409eff;
}

.stage-icon-completed {
  color: #67c23a;
}

.ml-8 {
  margin-left: 32px;
}

.close-reason {
  color: #f56c6c;
  font-weight: 500;
}

.action-section {
  display: flex;
  justify-content: center;
  gap: 16px;
  padding-top: 20px;
  border-top: 1px solid #e4e7ed;
}

.empty-review {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  text-align: center;
  background: #fafafa;
  border-radius: 8px;
  border: 1px dashed #d9d9d9;
}

.empty-icon {
  color: #d9d9d9;
  font-size: 48px;
  margin-bottom: 16px;
}

.empty-text {
  width: 100%;
}

.empty-title {
  font-weight: 500;
  color: #303133;
  margin-bottom: 8px;
  font-size: 16px;
}

.empty-desc {
  font-size: 14px;
  color: #909399;
  line-height: 1.5;
}
</style>
